import os.path

from xml.dom.minidom import parse, parseString
from projectInfo import *

class ProjectFileParser:
  def __init__(self):
    pass

  def parse(self, filename):
    if not os.path.exists(filename):
      raise Exception('Can not find the special file: %s' % filename)

    dom = parse(filename)

    # get project properties
    propNode = dom.getElementsByTagName('Properties')[0]
    if not propNode.hasChildNodes():
      raise Exception('Can not get properties of project.')

    projInfo = self.parseProperties(propNode.childNodes)

    if projInfo is None:
      raise Exception('Can not get properties of project.')

    # get items
    itemsNode = dom.getElementsByTagName('Items')[0]
    if propNode.hasChildNodes():
      self.parseItems(itemsNode.childNodes, projInfo)

    return projInfo
  
  def parseProperties(self, propNodelist):
    if propNodelist is None or len(propNodelist) == 0:
      return None

    projInfo = ProjectInfo()
    for node in propNodelist:
      if node.nodeType == node.ELEMENT_NODE:
        if node.nodeName.lower() == 'name':
          projInfo.setName(self.getNodeText(node))
        elif node.nodeName.lower() == 'path':
          projInfo.setPath(self.getNodeText(node))
        elif node.nodeName.lower() == 'version':
          projInfo.setVersion(self.getNodeText(node))
        elif node.nodeName.lower() == 'author':
          projInfo.setAuthor(self.getNodeText(node))
        elif node.nodeName.lower() == 'lisence':
          projInfo.setLisence(self.getNodeText(node))
        elif node.nodeName.lower() == 'mainscript':
          projInfo.setMainScript(self.getNodeText(node))
        elif node.nodeName.lower() == 'description':
          projInfo.setDescription(self.getNodeText(node))

    return projInfo

  def parseItems(self, itemNodelist, parent):
    if itemNodelist is None or parent is None:
      return

    itemlist = parent.getItems()
    for itemNode in itemNodelist:
      if itemNode.nodeType == itemNode.ELEMENT_NODE:
        if not itemNode.hasAttribute('name'):
          continue

        if itemNode.nodeName.lower() == 'folder':
          item = ProjectItem(itemNode.getAttribute('name'), ProjectItemType.Folder, parent)
          itemlist.append(item)

          if itemNode.hasChildNodes():
            self.parseItems(itemNode.childNodes, item)
        elif itemNode.nodeName.lower() == 'file':
          fileName = itemNode.getAttribute('name')

          splitedName = fileName.split(os.path.extsep)
          fileType = ProjectItemType.File
          if len(splitedName) > 1:
            if splitedName[1].lower() == 'py':
              fileType = ProjectItemType.PyFile
            elif splitedName[1].lower() == 'cfg':
              fileType = ProjectItemType.CfgFile
            elif splitedName[1].lower() == 'ini':
              fileType = ProjectItemType.IniFile
            elif splitedName[1].lower() == 'xml':
              fileType = ProjectItemType.XmlFile
            elif splitedName[1].lower() == 'png' or splitedName[1].lower() == 'bmp' or splitedName[1].lower() == 'ico' or splitedName[1].lower() == 'jpg':
              fileType = ProjectItemType.ImgFile

          item = ProjectItem(fileName, fileType, parent)
          itemlist.append(item)

  def getNodeText(self, node):
    if node is None:
      return ''

    if not node.hasChildNodes():
      if node.nodeType == node.TEXT_NODE:
        return node.nodeValue
      else:
        return ''

    text = ''
    childNodes = node.childNodes
    for child in childNodes:
      if child.nodeType == child.TEXT_NODE:
        text += child.nodeValue.strip(' \t%s' % os.linesep)
    return text


#################################################################
# test codes
if __name__ == '__main__':
  import sys
  import getopt
  
  def showItem(lst, lvl):
    for item in lst:
      print '%s+- %s: %s' % (' ' * lvl, item.getName(), item.getFullname())
      if len(item.getItems()) > 0:
        showItem(item.getItems(), lvl + 1)

  try:
    opts, args = getopt.getopt(sys.argv[1:], "hd:v", ["help", "filename="])
  except getopt.GetoptError, err:
    print 'Get opt failed.%s%s' % (os.linesep, str(err))
    sys.exit(2)
        
  filename = ''
  for opt, arg in opts:
    if opt.lower() == '--filename' or opt.lower() == '--f':
      filename = os.path.realpath(arg)
      print 'Source File: %s' % filename
      print '------------------------------------'

  if filename == '':
    print 'Please enter a file name by \'--filename=\' or \'--f\' argument.'
    
  if not os.path.exists(filename):
    print 'Can not find the file: %s' % filename
    sys.exit(2)
    
  parser = ProjectFileParser()
  proj = parser.parse(filename)
  if proj is None:
    print 'Can not found special or parse error.%sFile: %s' % (os.linesep, filename)

  print '%s: %s' % (proj.getName(), proj.getPath())
  showItem(proj.getItems(), 1)
